package pl.cba.solgar.game.rogal.console;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;

public class Console
{
	private ConsoleCell[][] buffer;

	private final int consoleWidth;
	private final int consoleHeight;

	private final int fontWidth;
	private final int fontHeight;

    private int translateX;
	private int translateY;

	private Color currentColor = Color.white;

	public Console(int consoleWidth, int consoleHeight, int fontHeight, int fontWidth)
	{
		this.consoleWidth = consoleWidth;
		this.consoleHeight = consoleHeight;
		this.fontWidth = fontWidth;
		this.fontHeight = fontHeight;

		buffer = new ConsoleCell[consoleWidth][consoleHeight];

		for (int y = 0; y < buffer[0].length; ++y)
			for (int x = 0; x < buffer.length; ++x)
				buffer[x][y] = new ConsoleCell();

		clear();
	}

	public void resetTranslate() {
		translateX = 0;
		translateY = 0;
	}

	public int getTranslateX() {
		return translateX;
	}

	public void setTranslateX(int translateX) {
		this.translateX = translateX;
	}

	public int getTranslateY() {
		return translateY;
	}

	public void setTranslateY(int translateY) {
		this.translateY = translateY;
	}

	public void clear()
	{
		for (int y = 0; y < buffer[0].length; ++y)
		{
			for (int x = 0; x < buffer.length; ++x)
			{
				ConsoleCell cell = buffer[x][y];
				cell.color = Color.black;
				cell.isBackgroundFilled = false;
				cell.backgroundColor = Color.black;
				cell.char_string = " ";
			}
		}
	}

	public void setColor(Color color)
	{
		currentColor = color;
	}

	public boolean setChar(char c, int x, int y, Color color)
	{
		x += translateX;
		y += translateY;
		if (x >= consoleWidth || y >= consoleHeight || x < 0 || y < 0)
			return false;
		buffer[x][y].char_string = Character.toString(c);
		buffer[x][y].color = color;
		buffer[x][y].isBackgroundFilled = false;
		return true;
	}

	public boolean setChar(char c, int x, int y, Color color, Color backgroundColor)
	{
		x += translateX;
		y += translateY;
		if (x >= consoleWidth || y >= consoleHeight || x < 0 || y < 0)
			return false;
		buffer[x][y].char_string = Character.toString(c);
		buffer[x][y].color = color;
		if (backgroundColor != null)
		{
			buffer[x][y].isBackgroundFilled = true;
			buffer[x][y].backgroundColor = backgroundColor;
		}
		else
		{
			buffer[x][y].isBackgroundFilled = false;
			buffer[x][y].backgroundColor = null;
		}
		return true;
	}

	public void setBackgroundColor(int x, int y, Color color, boolean enable)
	{
		x += translateX;
		y += translateY;
		buffer[x][y].isBackgroundFilled = enable;
		buffer[x][y].backgroundColor = color;
	}

	public void disableBackground(int x, int y)
	{
		x += translateX;
		y += translateY;
		buffer[x][y].isBackgroundFilled = false;
	}

	public void enableBackground(int x, int y)
	{
		x += translateX;
		y += translateY;
		buffer[x][y].isBackgroundFilled = true;
	}

	public int print(String text, int x, int y)
	{
		x += translateX;
		y += translateY;
		return print(text, x, y, currentColor, Color.black);
	}

	public int print(String text, int x, int y, Color color, Color background)
	{
		x += translateX;
		y += translateY;
		int printed = 0;
		for (int charIndex = 0; charIndex < text.length(); ++charIndex) {
			if (background == null) {
				if (setChar(text.charAt(charIndex), x + charIndex, y, color))
					printed += 1;
			}
			else {
				if (setChar(text.charAt(charIndex), x + charIndex, y, color, background))
					printed += 1;
			}
		}
		return printed;
	}

	public void render(Graphics g)
	{
		for (int y = 0; y < buffer[0].length; ++y)
		{
			for (int x = 0; x < buffer.length; ++x)
			{
				if (buffer[x][y].isBackgroundFilled && buffer[x][y].backgroundColor != Color.black)
				{
					g.setColor(buffer[x][y].backgroundColor);
					g.fillRect(x*fontWidth, y*fontHeight, fontWidth, fontHeight);
				}
				g.setColor(buffer[x][y].color);
				g.drawString(buffer[x][y].char_string, x*fontWidth, y*fontHeight);
			}
		}
	}

	public int getConsoleWidth() {
		return consoleWidth;
	}

	public int getConsoleHeight() {
		return consoleHeight;
	}
}
